/*
 * @Version: 0.0.1
 * @Author: ider
 * @Date: 2020-10-30 15:47:19
 * @LastEditors: ider
 * @LastEditTime: 2020-11-05 14:01:09
 * @Description:颠覆度所有文章进行计算
 */
package store

import (
	"bufio"
	"encoding/json"
	"io"
	"os"
	"strings"
	"sync"
	"time"

	"github.com/emirpasic/gods/sets/hashset"
	log "github.com/sirupsen/logrus"
)

func init() {
	log.SetOutput(os.Stdout)
	// 设置日志级别为warn以上
}

/**
 * @description: 统计所有集合的节点情况，全部加载到内存，得到linksin,linksout,空间换时间
 */
func ReadAllLinksChanRef() (linksoutRef, linksinRef *map[string]*hashset.Set, autherCountMap *map[string]int) {
	linksoutRef = new(map[string]*hashset.Set)
	*linksoutRef = make(map[string]*hashset.Set)
	linksinRef = new(map[string]*hashset.Set)
	*linksinRef = make(map[string]*hashset.Set)
	autherCountMap = new(map[string]int)
	*autherCountMap = make(map[string]int)

	fi, err := os.Open("/home/ni/data/mag/all_refed_authors_data.txt")
	if err != nil {
		log.Printf("Error: %s\n", err)
		return
	}
	defer fi.Close()
	start_time := time.Now()
	br := bufio.NewReader(fi)

	ch := make(chan string, 1000)
	chOut := make(chan NewChanObj, 1000)
	const threaCount = 20
	var wg = sync.WaitGroup{}
	var wgOut = sync.WaitGroup{}
	wg.Add(threaCount)
	wgOut.Add(1)
	// 处理数据的协程
	for i := 0; i < threaCount; i++ {
		go func() {
			for a := range ch {
				strs := strings.Split(a, "\t")
				linksoutArray := []string{}
				var autherArray = []interface{}{}
				if len(strs) >= 3 {
					err := json.Unmarshal([]byte(strs[2]), &linksoutArray)
					if err != nil {
						log.Printf("Error: %s\n", err)
						log.Printf("%+v\n", string(a))
						return
					}
					err = json.Unmarshal([]byte(strs[3]), &autherArray)
					if err != nil {
						log.Printf("Error: %s\n", err)
						log.Printf("%+v\n", string(a))
						return
					}
				} else {
					log.Println("strs", strs)
				}
				// 不过滤linksout 数量
				// if len(linksoutArray) > 0 {
				co := NewChanObj{Key: strs[0], S: &linksoutArray, AC: len(autherArray)}
				chOut <- co
				// }
			}
			wg.Done()
		}()
	}
	// linksout保存到字典,linksin保存到字典
	go func() {
		for chobj := range chOut {
			// 保存作者数
			(*autherCountMap)[chobj.Key] = chobj.AC
			// 保存 linksout
			(*linksoutRef)[chobj.Key] = hashset.New()
			for _, s := range *chobj.S {
				(*linksoutRef)[chobj.Key].Add(s)
			}
			// save linksin
			for _, sid := range *chobj.S {
				if _, ok := (*linksinRef)[sid]; ok {
					// 存在
					(*linksinRef)[sid].Add(chobj.Key)
				} else {
					// 不存在
					(*linksinRef)[sid] = hashset.New(chobj.Key)
				}
			}
		}
		wgOut.Done()
	}()

	// 加载到队列
	// count := 0
	for {
		a, c := br.ReadString('\n')
		if c == io.EOF {
			break
		}
		ch <- a
		// count += 1
		// if count > 100000 {
		// 	break
		// }
	}
	close(ch)
	wg.Wait()
	close(chOut)
	wgOut.Wait()
	end_time := time.Now()
	log.Println("read all links:", end_time.Sub(start_time))
	return
}

func Mathod2_try() {
	linksoutRef, linksinRef, autherCountMap := ReadAllLinksChanRef()
	log.Println("linksoutRef", len(*linksoutRef))
	log.Println("linksinRef", len(*linksinRef))
	log.Println("auther exit count", len(*autherCountMap))
}
